#ifndef PATTERN_HPP
#define PATTERN_HPP
#include <utility>
#include<vector>
#include<algorithm>
#include "polygon.hpp"
using namespace std;
class Pattern{

    vector<Polygon> polygons;
    int width, height;
    Polygon nb_polygon;
    int rotate_type; //记录旋转方向，本属性只在搜索道的匹配框中使用
    Point left_node; //记录左下角，本属性只在搜索道的匹配框中使用

public:
    // default constructor
    Pattern(){}
    //构造函数
    Pattern(vector<Polygon> ps, int w, int h, int rot = 0, Point ln = Point(0, 0)) {
        polygons = std::move(ps);
        width = w;
        height = h;
        //对polygon进行排序
        sort(polygons.begin(), polygons.end());
        rotate_type = rot;
        left_node = ln;
    }

    //bool 相等
    bool operator==( Pattern &other) const {
        if (polygons.size() != other.polygons.size())
            return false;
        if (width != other.width || height != other.height)
            return false;
        
        for (int i = 0; i < polygons.size(); i++) {
            bool f = false;
            for (int j = 0; j < polygons.size(); j++){
                if (polygons[i] == other.polygons[j]){
                    f = true;
                    break;
                }
            }  
            if(!f) return false;
        }
        return true;
    }

    //找到最复杂的一个多边形
    void find_nb_polygon() {
        //TODO: 增加可变的nb_polygon，需在search_first确定边框改为确定边框范围
        vector<Polygon> inside_polygon;
        for (auto& polygon: polygons){
            if(polygon.is_inside(width, height) && polygon.has_static_node())
                inside_polygon.emplace_back(polygon);
        }
        nb_polygon = inside_polygon[0];
        for (int i = 1; i < inside_polygon.size(); i++) {
            if (inside_polygon[i].get_node_size() > nb_polygon.get_node_size()
            || (inside_polygon[i].get_node_size() == nb_polygon.get_node_size() && inside_polygon[i].get_area() > nb_polygon.get_area()))
                nb_polygon = inside_polygon[i];
        }
    }
    
    // 将Polygon排序
    /*void sort_polygon() {
        sort(polygons.begin(), polygons.end());
    }*/

    // 将pattern 中所有点与left_node相减，变为相对位置
    void normalization(){
        for(auto &polygon: polygons){
            polygon.set_left_node(polygon.get_left_node() - left_node);
        }
    }

    Pattern get_rotate(int rotate_type) {
        vector<Polygon> sub_ps;

        int add_square[8][2] {
                {0, 0},
                {0, width},
                {width, height},
                {height, 0},
                {0, height},
                {0, 0},
                {width, 0},
                {height, width}
        };
        for (auto & polygon : polygons) {
            sub_ps.push_back(polygon.polygon_rotate(rotate_type, add_square[rotate_type][0], add_square[rotate_type][1]));
        }
        Pattern p;
        if (rotate_type % 2 == 0)
            p = Pattern(sub_ps, width, height);
        else
            p = Pattern(sub_ps, height, width);
        p.find_nb_polygon();
        //p.sort_polygon();
        //p.set_rotate_type(rotate_type);
        return p;
    }

    Polygon get_nb_polygon() {
        return nb_polygon;
    }

    int get_width() const {
        return width;
    }

    int get_height() const {
        return height;
    }

    Point get_left_node() const{
        return left_node;
    }

    void set_left_node(Point p){
        left_node = p;
    }

    void set_rotate_type(int rot) {
        rotate_type = rot;
    }

    void print_bound(FILE *f) {
        int x1 = left_node.get_x();
        int y1 = left_node.get_y();
        int x2 = left_node.get_x() + width;
        int y2 = left_node.get_y() + height;
        fprintf(f, "(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", x1, y1, x2, y1, x2, y2, x1, y2);
    }

    void printf() {
        cout << "polygons:" << endl;
        for (int i = 0; i < polygons.size(); i++) {
            polygons[i].printf();
        }
        cout << "width="<< width << " height=" << height << endl;
    }

};
#endif